package it.polimi.TravelDream.ejb.userManager;

import java.security.Principal;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJBContext;
import javax.ejb.Stateless;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import it.polimi.TravelDream.ejb.dtos.AddressDTO;
import it.polimi.TravelDream.ejb.dtos.UserDTO;
import it.polimi.TravelDream.ejb.eaos.UserMgr;
import it.polimi.TravelDream.ejb.entities.*;

/**
 * Session Bean implementation class UserMgrBean
 */
@Stateless
public class UserMgrBean implements UserMgr {

    @PersistenceContext
    private EntityManager em;
	
	@Resource
	private EJBContext context;

    /**
     * Default constructor. 
     */
    public UserMgrBean() {
        // TODO Auto-generated constructor stub
    }

	@Override
	public void save(UserDTO userDTO, AddressDTO addressDTO) {
		Address newAddress = new Address(addressDTO);
		User newUser = new User(userDTO);
		List<Group> groups = new ArrayList<Group>();
		groups.add(Group.USER);
		newUser.setGroups(groups);
		newUser.setAddress(newAddress);
		em.persist(newAddress);
		em.persist(newUser);
	}
	
	//modifica utente preesistente
	@Override
	@RolesAllowed({Group._USER,Group._ADMIN})
	public void update(UserDTO userDTO, AddressDTO addressDTO) {
		Address address = new Address(addressDTO);
		User user = new User(userDTO);
		
		em.merge(user);
		em.merge(address);
		
	}
	
	//metodo per prelevare lato web tier le informazioni dell'utente loggato
	@Override
	public UserDTO getUserDTO() {
		UserDTO userDTO = convertUserToDTO(getPrincipalUser());
		return userDTO;
	}
	
	@Override
	public AddressDTO getAddressDTO() {
		AddressDTO addressDTO = convertAddressToDTO(getPrincipalUser().getAddress());
		return addressDTO;
	}
	
	@Override
	@RolesAllowed({Group._USER})
	public void unregister() {
		remove(getPrincipalUser());
	}
	
	public User find(String username) {
    	return em.createNamedQuery(User.FIND_USER_BY_USERNAME, User.class).setParameter("username", username).getSingleResult();
    }
	
	public List<User> getAllUsers() {
    	return em.createNamedQuery(User.FIND_ALL, User.class)
                .getResultList();
    }
	
	 public void remove(String username) {
			User user = find(username);
	        em.remove(user);
		}
	 
	 public void remove(User user) {
	    	em.remove(user);
		}
	 
	 public User getPrincipalUser() {
	    	return find(getPrincipalUsername());
	    }
		
	 public String getPrincipalUsername() {
		 	Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
	    	return principal.getName();
	    }
	 private UserDTO convertUserToDTO(User user) {
			UserDTO userDTO = new UserDTO();
			userDTO.setUsername(user.getUsername());
			userDTO.setName(user.getName());
			userDTO.setSurname(user.getSurname());
			userDTO.setEmail(user.getEmail());
			return userDTO;
		}
	 
	 private AddressDTO convertAddressToDTO (Address a){
	    	AddressDTO addressDTO = new AddressDTO();
	    	addressDTO.setStreet(a.getStreet());
	    	addressDTO.setStreetNumber(a.getStreetNumber());
	    	addressDTO.setCity(a.getCity());
	    	addressDTO.setCap(a.getCap());
	    	addressDTO.setDistrict(a.getDistrict());
	    	addressDTO.setNation(a.getNation());
	    	return addressDTO;
	    } 
}
